<template>
  <div class="config-page">

    <!-- 搜索栏 -->
    <div class="search-bar">
      <input
        v-model="searchKeyword"
        class="form-control"
        placeholder="搜索配置名称/配置描述"
        @keyup.enter="handleSearch"
      />
      <input
        v-model="searchIdNumber"
        class="form-control"
        placeholder="搜索身份证号码/护照号码"
        @keyup.enter="handleSearch"
      />
      <el-select
        v-model="searchFenceType"
        placeholder="请选择围栏类型"
        style="width: 160px;"
        clearable
      >
        <el-option :key="1" :label="'禁入围栏'" :value="1">禁入围栏</el-option>
        <el-option :key="2" :label="'禁出围栏'" :value="2">禁出围栏</el-option>
      </el-select>
      <el-select
        v-model="searchFenceStatus"
        placeholder="请选择监控状态"
        style="width: 160px;"
        clearable
      >
        <el-option :key="1" :label="'正在监控'" :value="1">正在监控</el-option>
        <el-option :key="2" :label="'已经失效'" :value="2">已经失效</el-option>
      </el-select>
      <button @click="handleSearch" class="btn btn-secondary">
        <i class="fa fa-search mr-1"></i>搜索
      </button>
      <button @click="clearSearch" class="btn btn-outline-secondary">
        <i class="fa fa-refresh mr-1"></i>清空
      </button>
      <button @click="openCreateConfigDialog" class="btn btn-primary">
        <i class="fa fa-plus mr-1"></i> 新增围栏
      </button>
    </div>

    <!-- 配置表格 -->
    <div class="table-container">
      <el-table
        :data="configPage.list"
        border
        stripe
        :row-class-name="rowClassNameHandler"
        style="width: 100%"
      >
        <el-table-column label="围栏名称" prop="name" width="190"/>
        <el-table-column label="围栏类型" prop="fenceType" width="100">
          <template #default="scope">
            <span v-if="scope.row.fenceType === 1">禁入围栏</span>
            <span v-else-if="scope.row.fenceType === 2">禁出围栏</span>
          </template>
        </el-table-column>
        /
        <el-table-column label="开始时间" prop="startTime" width="180"/>
        <el-table-column label="结束时间" prop="endTime" width="180"/>
        <el-table-column label="创建时间" prop="createTime" width="180"
                         :formatter="formatDateTime"/>
        <el-table-column label="操作" align="center">
          <template #default="scope">
            <button @click.stop="handleEditConfig(scope.row)" class="btn btn-sm btn-primary">
              <i class="fa fa-edit mr-1"></i>围栏编辑
            </button>
            <button @click.stop="handleViewMap(scope.row)" class="btn btn-sm btn-info">
              <i class="fa fa-map-marker mr-1"></i>地图画圈
            </button>
            <button @click.stop="handleShowPersonList(scope.row)" class="btn btn-sm btn-primary">
              <i class="fa fa-edit mr-1"></i>涉及人员
            </button>
            <button @click.stop="handleDeleteConfig(scope.row.id)" class="btn btn-sm btn-danger">
              <i class="fa fa-trash mr-1"></i>删除
            </button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 分页 -->
    <div class="pagination-container">
      <el-pagination
        @size-change="handlePageSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pageParam.pageNo"
        :page-sizes="[10, 20, 50]"
        :page-size="pageParam.pageSize"
        :total="configPage.total"
        layout="total, sizes, prev, pager, next, jumper"
      />
    </div>

    <el-drawer
      v-model="showPersonListDrawer"
      title="添加涉及人员"
      direction="rtl"
      size="55%"
      :resizable=true
    >
      <!-- 标题下方的阴影分隔线 -->
      <div class="header-divider"></div>

      <!-- 人员列表组件 -->
      <PersonFenceWarnDrawer
        ref="personListRef"
        :warn-config-id="currentRow?.id"
        @cancel="showPersonListDrawer = false"
      />
    </el-drawer>

    <!-- 新增/编辑配置弹窗（可移动） -->
    <el-dialog
      v-model="showConfigDialog"
      :title="isEditConfig ? '编辑围栏配置' : '新建围栏配置'"
      width="500px"
      :close-on-click-modal="false"
      ref="configDialogRef"
      class="draggable-dialog"
    >
      <div class="form-group">
        <label>围栏名称 <span class="required">*</span>:</label>
        <input
          v-model="configForm.name"
          class="form-control"
          required
          placeholder="请输入围栏名称"
        />
      </div>
      <div class="form-group">
        <label>围栏类型 <span class="required">*</span>:</label>
        <el-radio-group v-model="configForm.fenceType">
          <el-radio :label="1">禁入</el-radio>
          <el-radio :label="2">禁出</el-radio>
        </el-radio-group>
      </div>
      <div class="form-group">
        <label>开始时间 <span class="required">*</span>:</label>
        <el-date-picker
          v-model="configForm.startTime"
          type="datetime"
          class="w-full"
          placeholder="选择开始时间"
          value-format="YYYY-MM-DD HH:mm:ss"
          required
        />
      </div>

      <div class="form-group">
        <label>结束时间 <span class="required">*</span>:</label>
        <el-date-picker
          v-model="configForm.endTime"
          type="datetime"
          class="w-full"
          placeholder="选择结束时间"
          value-format="YYYY-MM-DD HH:mm:ss"
          required
        />
      </div>

      <div class="form-group">
        <label>可选区县 :</label>
        <el-select
          v-model="configForm.districtCode"
          class="w-full"
          clearable
          placeholder="请选择区县"
          @change="handleDistrictChange"
        >
          <el-option value="">-- 请选择 --</el-option>
          <el-option
            v-for="district in districtList"
            :key="district.code"
            :label="district.name"
            :value="district.code"
          />
        </el-select>
      </div>

      <div class="form-group">
        <label>配置描述:</label>
        <textarea v-model="configForm.description" class="form-control" rows="3"
                  placeholder="可选描述信息"></textarea>
      </div>

      <template #footer>
        <button @click="showConfigDialog = false" class="btn btn-secondary mr-5">
          <i class="fa fa-times mr-1"></i>取消
        </button>
        <button @click="submitConfigForm" class="btn btn-primary">
          <i class="fa fa-check mr-1"></i>提交
        </button>
      </template>
    </el-dialog>

    <!-- 地图弹窗（可移动） -->
    <el-dialog
      v-model="showMapDialog"
      title="地图编辑器"
      :width="'90%'"
      :max-height="'90vh'"
      :fullscreen="false"
      :close-on-click-modal="false"
      ref="mapDialogRef"
      class="draggable-dialog fixed-size-dialog"
    >
      <div class="map-dialog-container">
        <div id="map" ref="mapRef" class="map"></div>

        <!-- 地图控制按钮组 -->
        <div class="map-controls">
          <button
            @click="toggleDrawMode"
            class="control-btn"
            :class="{ 'active': isDrawing }"
            title="绘制多边形"
          >
            <i class="fa fa-pencil fa-lg"></i>画圈
          </button>
          <button
            @click="saveAllPolygons"
            class="control-btn save-btn"
            title="保存多边形"
          >
            <i class="fa fa-save fa-lg"></i>保存
          </button>
          <button
            @click="clearAllPolygons"
            class="control-btn clear-btn"
            title="清空多边形"
          >
            <i class="fa fa-trash fa-lg"></i>清空
          </button>
          <button
            @click="loadAllPolygons"
            class="control-btn load-btn"
            title="重新加载多边形"
          >
            <i class="fa fa-refresh fa-lg"></i>加载
          </button>
          <!-- 点判断显示切换按钮 -->
          <button
            @click="togglePointJudge"
            class="control-btn judge-btn"
            :class="{ 'active': showPointJudge }"
            title="点-in-多边形判断"
          >
            <i class="fa fa-crosshairs fa-lg"></i>测试
          </button>
        </div>

        <!-- 多边形编辑框 -->
        <div v-if="selectedPolygon" class="polygon-info">
          <h3>多边形属性</h3>
          <div class="form-group">
            <label>名称:</label>
            <input
              v-model="selectedPolygon.name"
              class="form-control"
            />
          </div>
          <!-- 新增：面积信息显示 -->
          <div class="form-group">
            <label>面积:</label>
            <div class="area-display">
              {{ formatArea(selectedPolygon.area || 0) }}
              <select
                v-model="areaUnit"
                class="area-unit-select"
                @change="updateAreaDisplay"
              >
                <option value="sqm">平方米</option>
                <option value="sqkm">平方公里</option>
                <option value="sqmi">平方英里</option>
              </select>
            </div>
          </div>
          <div class="form-group">
            <label>顶点数量:</label>
            <div class="readonly-value">{{ selectedPolygon.pointCount || 0 }}</div>
          </div>
          <div class="form-group">
            <label>边框颜色:</label>
            <input
              type="color"
              v-model="selectedPolygon.strokeColor"
              class="form-control"
            />
          </div>
          <div class="form-group">
            <label>边框宽度:</label>
            <input
              type="number"
              v-model="selectedPolygon.strokeWeight"
              class="form-control"
              min="1"
              max="20"
              step="1"
            />
          </div>
          <div class="form-group">
            <label>填充颜色:</label>
            <input
              type="color"
              v-model="selectedPolygon.fillColor"
              class="form-control"
            />
          </div>
          <div class="form-group">
            <label>填充透明度:</label>
            <input
              type="number"
              step="0.1"
              v-model="selectedPolygon.fillOpacity"
              class="form-control"
              min="0"
              max="1"
            />
          </div>
          <div class="form-group">
            <label>排序号:</label>
            <input
              type="number"
              v-model="selectedPolygon.sortOrder"
              class="form-control"
              min="0"
              step="1"
            />
          </div>
          <button @click="updatePolygon" class="btn btn-primary">
            <i class="fa fa-check mr-1"></i>保存
          </button>
          <button @click="deleteSelectedPolygon" class="btn btn-danger">
            <i class="fa fa-trash mr-1"></i>删除
          </button>
          <button @click="deselectPolygon" class="btn btn-secondary">
            <i class="fa fa-times mr-1"></i>取消
          </button>
        </div>

        <!-- 点-in-多边形判断面板 -->
        <div v-if="showPointJudge" class="point-judge">
          <div class="panel-header">
            <h3>点-与-多边形关系判断</h3>
            <button @click="showPointJudge = false" class="close-btn custom-close-icon"></button>
          </div>
          <div class="form-group">
            <label>目标配置ID:</label>
            <input
              type="text"
              v-model="judgeReq.configId"
              class="form-control"
              readonly
            />
          </div>
          <div class="form-group">
            <label>经度(lng):</label>
            <div class="input-with-btn">
              <input
                type="number"
                step="0.000001"
                v-model="judgeReq.lng"
                class="form-control"
                required
              />
              <button @click="startPickCoordinate('lng')" class="pick-btn"
                      :class="{active: pickingCoordinate === 'lng'}">
                <i class="fa fa-map-marker"></i>拾取坐标
              </button>
            </div>
          </div>
          <div class="form-group">
            <label>纬度(lat):</label>
            <div class="input-with-btn">
              <input
                type="number"
                step="0.000001"
                v-model="judgeReq.lat"
                class="form-control"
                required
              />
            </div>
          </div>
          <div class="form-group">
            <label>详细地址:</label>
            <div class="input-with-btn">
              <input
                type="text"
                v-model="judgeReq.address"
                class="form-control"
                required
              />
            </div>
          </div>
          <!-- 新增的人员搜索部分 -->
          <div class="form-group">
            <label>选取人员:</label>
            <div class="input-with-btn">
              <input
                type="text"
                v-model="judgeReq.idcard"
                class="form-control"
                placeholder="请输入证件号查询"
                required
                :disabled="loading"
              />
            </div>
            <button
              @click="searchPerson"
              class="btn btn-primary"
              :disabled="loading || !judgeReq.idcard"
            >
              <i class="fa fa-search mr-1"></i>
              {{ loading ? '查询中...' : '查询人员' }}
            </button>
            <div v-if="judgeReq.personId" class="person-id-display">
              【人员ID: {{ judgeReq.personId }}】-【人员姓名：{{ personData?.name }}】
            </div>
            <div v-if="searchError" class="search-error">
              <i class="fa fa-exclamation-circle"></i> {{ searchError }}
            </div>
          </div>
          <button @click="judgePointInPolygon" class="btn btn-primary">
            <i class="fa fa-search mr-1"></i>判断
          </button>
          <div v-if="judgeResult" class="judge-result">
            <p>判断结果: {{ judgeResult.isInside ? '在多边形内' : '在多边形外' }}</p>
            <div v-if="judgeResult.isInside">
              <p>所在多边形:</p>
              <ul>
                <li v-for="poly in judgeResult.insidePolygons" :key="poly.id">
                  {{ poly.name }} (配置: {{ poly.configName }})
                </li>
              </ul>
            </div>
          </div>
          <div v-if="isPickingCoordinate" class="pick-notice">
            <i class="fa fa-info-circle"></i> 请在地图上点击选取点
          </div>
        </div>

        <!-- 状态提示 -->
        <div v-if="message" class="status-message">{{ message }}</div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {nextTick, onMounted, onUnmounted, reactive, ref, toRefs, watch} from 'vue';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import 'leaflet-draw/dist/leaflet.draw.css';
import 'leaflet-draw';
import * as UserApi from '@/api/member/user'
import {MapConfigApi, MapPolygonApi, PointInPolygonApi} from '@/api/member/map/mapConfigApi';
import PersonFenceWarnDrawer from "@/views/warnSetting/components/PersonFenceWarnDrawer.vue";

defineOptions({name: 'FenceIndex'})

// 扩展Leaflet类型定义
declare module 'leaflet' {
  interface PathOptions {
    zIndexOffset?: number;
  }

  interface DrawHandler {
    enable: () => void;
    disable: () => void;
    finishDrawing?: () => void;
    _isDrawing?: boolean;
  }

  interface DrawHandlers {
    polygon?: DrawHandler;
    Polygon?: DrawHandler;
  }
}

// 类型定义 - 与后端保持一致
interface DrawHandlerCollection {
  [key: string]: L.DrawHandler;
}

interface MapConfig {
  id: string;
  name: string;
  description: string;
  provinceCode: string;
  cityCode: string;
  districtCode: string;
  centerLng: number;
  centerLat: number;
  zoomLevel: number;
  isDefault: number;
  startTime: string;
  endTime: string;
  fenceType: number;
}

interface MapPolygonPoint {
  id?: number;
  ringIndex: number;
  lng: number;
  lat: number;
  pointIndex: number;
}

// 与后端MapPolygonDO完全匹配的类型定义
interface MapPolygon {
  id?: string;
  configId: string;
  name: string;
  strokeColor: string;
  strokeWeight: number;
  fillColor: string;
  fillOpacity: number;
  roomLevel: 13;
  sortOrder: number;
  points: MapPolygonPoint[];
  coordinates: number[][][];
  // 以下字段由计算或后端返回
  area?: number;         // 面积，平方米
  pointCount?: number;   // 顶点数量
}

interface JudgeRequest {
  configId: string;
  lng: number;
  lat: number;
  personId: number | null;
  idcard: string;
  address: string;
}

interface JudgeResult {
  isInside: boolean;
  insidePolygons?: Array<{
    id: string;
    name: string;
    configId: string;
    configName: string;
  }>;
}

const districtList = [
  {name: '上城区', code: '330102', longitude: 120.16707, latitude: 30.25708},
  {name: '下城区', code: '330103', longitude: 120.14507, latitude: 30.27408},
  {name: '江干区', code: '330104', longitude: 120.18207, latitude: 30.26408},
  {name: '拱墅区', code: '330105', longitude: 120.13207, latitude: 30.28408},
  {name: '西湖区', code: '330106', longitude: 120.10507, latitude: 30.25408},
  {name: '滨江区', code: '330108', longitude: 120.19507, latitude: 30.21408},
  {name: '萧山区', code: '330109', longitude: 120.27507, latitude: 30.17408},
  {name: '余杭区', code: '330110', longitude: 120.09507, latitude: 30.31408},
  {name: '富阳区', code: '330111', longitude: 119.95507, latitude: 30.07408},
  {name: '临安区', code: '330112', longitude: 119.72507, latitude: 30.23408},
  {name: '桐庐县', code: '330122', longitude: 119.64507, latitude: 29.80408},
  {name: '淳安县', code: '330127', longitude: 119.05507, latitude: 29.61408},
  {name: '建德市', code: '330182', longitude: 119.27507, latitude: 29.49408}
]

// 响应式状态
const state = reactive({
  configPage: {list: [] as MapConfig[], total: 0},
  pageParam: {pageNo: 1, pageSize: 10},
  searchKeyword: '',
  searchIdNumber: '',
  searchFenceType: undefined as number | undefined,
  searchFenceStatus: undefined as number | undefined,
  warnType: 1,
  selectedConfigId: '',
  currentConfig: null as MapConfig | null,
  showConfigDialog: false,
  isEditConfig: false,
  isLoadingPolygons: false, // 多边形加载状态标识
  configForm: {
    id: '',
    name: '',
    description: '',
    startTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
    endTime: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().slice(0, 19).replace('T', ' '),
    provinceCode: '330000',
    cityCode: '330100',
    districtCode: '',
    centerLng: 120.15507,
    centerLat: 30.274084,
    zoomLevel: 13,
    isDefault: 0,
    warnType: 1,
    fenceType: 1
  },
  showMapDialog: false,
  polygons: [] as MapPolygon[],
  selectedPolygon: null as MapPolygon | null,
  isDrawing: false,
  message: '',
  showPointJudge: false,
  judgeReq: {
    configId: '',
    lng: 0,
    lat: 0,
    personId: null as number | null,  // 初始为null
    idcard: '',
    address: '',
  } as JudgeRequest,
  judgeResult: null as JudgeResult | null,
  areaUnit: 'sqm' as 'sqm' | 'sqkm' | 'sqmi', // 面积单位：平方米、平方公里、平方英里
  // 新增状态变量
  pickingCoordinate: '' as '' | 'lng' | 'lat', // 记录当前是否在拾取坐标及拾取类型
  tempMarker: null as L.Marker | null, // 临时标记点
  // 新增状态
  loading: false,          // 搜索加载状态
  searchError: ''          // 搜索错误信息
});

const {
  configPage,
  pageParam,
  searchKeyword,
  searchIdNumber,
  searchFenceType,
  searchFenceStatus,
  selectedConfigId,
  currentConfig,
  showConfigDialog,
  isEditConfig,
  configForm,
  showMapDialog,
  polygons,
  selectedPolygon,
  isDrawing,
  message,
  showPointJudge,
  judgeReq,
  judgeResult,
  areaUnit,
  pickingCoordinate,
  tempMarker,
  loading,
  searchError
} = toRefs(state);

// 新增计算属性判断是否正在拾取坐标
const isPickingCoordinate = computed(() => {
  return !!pickingCoordinate.value;
});

// 地图相关引用和实例
const currentConfigId = ref('');
const mapRef = ref<HTMLDivElement | null>(null);
let mapInstance: L.Map | null = null;
let drawControl: any = null;
let polygonLayer: L.FeatureGroup<L.Polygon> | null = null;
let polygonDrawHandler: L.DrawHandler | null = null;

// 弹窗引用（用于拖拽）
const configDialogRef = ref<HTMLElement | null>(null);
const mapDialogRef = ref<HTMLElement | null>(null);

// 抽屉显示状态
const showPersonListDrawer = ref(false);
const personListRef = ref<InstanceType<typeof PersonFenceWarnDrawer>>();

// 当前选中的行数据
const currentRow = ref<MapConfig | null>(null);

// 打开涉及人员抽屉
const handleShowPersonList = (row: MapConfig) => {
  currentRow.value = row;
  showPersonListDrawer.value = true;
  // 可以在这里直接触发数据刷新（如果子组件提供了方法）
  nextTick(() => {
    personListRef.value?.fetchPersonList(row.id);
  });
};

const formatDateTime = (row) => {
  // 获取毫秒时间戳
  const timestamp = row.createTime;
  // 处理无效时间的情况
  if (!timestamp) return '';

  // 转换为Date对象（注意：如果是13位时间戳直接使用，10位需要乘以1000）
  const date = new Date(timestamp);

  // 获取年月日时分秒
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');

  // 拼接成yyyy-MM-dd HH:mm:ss格式
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

// 处理区县选择变更，自动填充经纬度
const handleDistrictChange = () => {
  // 当未选择区县或清空选择时
  if (!configForm.value.districtCode) {
    // 清空经纬度输入框或设置默认值
    configForm.value.centerLng = 120.15507;
    configForm.value.centerLat = 30.274084;
    return;
  }

  // 查找选中的区县信息
  const selectedDistrict = districtList.find(
    district => district.code === configForm.value.districtCode
  );

  // 找到对应区县时填充经纬度
  if (selectedDistrict) {
    configForm.value.centerLng = selectedDistrict.longitude;
    configForm.value.centerLat = selectedDistrict.latitude;
  } else {
    // 未找到对应区县时清空
    configForm.value.centerLng = 120.15507;
    configForm.value.centerLat = 30.274084;
  }
};

// 消息提示
const setMessage = (text: string, duration = 3000) => {
  message.value = text;
  duration && setTimeout(() => message.value = '', duration);
};

// 切换点判断显示状态
const togglePointJudge = () => {
  state.showPointJudge = !state.showPointJudge;
  if (state.showPointJudge) {
    setMessage('点-in-多边形判断功能已开启');
  } else {
    setMessage('点-in-多边形判断功能已关闭');
  }
};

// ---------------------- 面积计算相关功能 ----------------------
/**
 * 使用 shoelace 公式计算多边形面积（平方米）
 * @param points 多边形顶点坐标数组 [lng, lat][]
 * @returns 面积（平方米）
 */
const calculatePolygonArea = (points: [number, number][]): number => {
  if (points.length < 3) return 0;

  // 地球半径（米）
  const R = 6378137;
  let area = 0;

  // 将经纬度转换为弧度
  const radPoints = points.map(([lng, lat]) => [
    lng * Math.PI / 180,
    lat * Math.PI / 180
  ]);

  const n = radPoints.length;
  for (let i = 0; i < n; i++) {
    const j = (i + 1) % n;
    const [lng1, lat1] = radPoints[i];
    const [lng2, lat2] = radPoints[j];

    // 计算面积增量
    const dLng = lng2 - lng1;
    const areaIncrement = (dLng * (2 + Math.sin(lat1) + Math.sin(lat2)));
    area += areaIncrement;
  }

  // 计算最终面积（平方米）
  area = Math.abs(area * R * R / 2);
  return area;
};

/**
 * 格式化面积显示
 * @param area 面积（平方米）
 * @returns 格式化后的面积字符串
 */
const formatArea = (area: number): string => {
  switch (areaUnit.value) {
    case 'sqkm': // 平方公里
      return (area / 1000000).toFixed(6);
    case 'sqmi': // 平方英里
      return (area / 2589988.11).toFixed(6);
    default: // 平方米
      return area.toFixed(2);
  }
};

/**
 * 更新面积显示（当单位改变时）
 */
const updateAreaDisplay = () => {
  // 当单位改变时，重新渲染即可，不需要额外计算
  if (selectedPolygon.value) {
    // 触发重新渲染
    selectedPolygon.value = {...selectedPolygon.value};
  }
};

// 初始化地图
const initMap = (centerLng = 120.1551, centerLat = 30.2741, zoom = 13) => {
  if (!mapRef.value) throw new Error('地图容器未找到');

  // if (mapInstance) {
  //   mapInstance.remove();
  // }
  if (mapInstance) {
    mapInstance.off('click', handleMapClick); // 移除旧的点击事件监听
    mapInstance.remove();
  }

  mapInstance = L.map(mapRef.value, {
    minZoom: 10,
    maxZoom: 16,
    crs: L.CRS.EPSG3857,
    attributionControl: true
  }).setView([centerLat, centerLng], zoom);

  // 加载地图瓦片
  L.tileLayer(import.meta.env.VITE_MAP_TILE_URL, {
    errorTileUrl: '',
    attribution: '地图数据 © 高德地图',
    tileSize: 256,
    zoomOffset: 0
  }).addTo(mapInstance);

  // L.tileLayer('http://localhost:8000/map/{z}/{x}/{y}/tile.png', {
  //   errorTileUrl: '',
  //   attribution: '地图数据 © 高德地图',
  //   tileSize: 256,
  //   zoomOffset: 0
  // }).addTo(mapInstance);

  // 初始化多边形图层
  polygonLayer = L.featureGroup<L.Polygon>().addTo(mapInstance);
  initDrawControl();

  // 添加地图点击事件监听
  mapInstance.on('click', handleMapClick);
};

// 初始化绘制控件
const initDrawControl = () => {
  if (!mapInstance || !polygonLayer) return;

  const drawOptions = {
    edit: {
      featureGroup: polygonLayer,
      edit: {enabled: true},
      remove: {enabled: true},
      selectedPathOptions: {color: '#ff6b6b', weight: 3, opacity: 1}
    },
    draw: {
      polyline: false,
      rectangle: false,
      circle: false,
      marker: false,
      circlemarker: false,
      polygon: {
        allowIntersection: false,
        drawError: {color: '#ff6b6b', message: '不能交叉！'},
        shapeOptions: {
          color: '#4ecdc4',
          weight: 2,
          opacity: 0.8,
          fillOpacity: 0.3,
          zIndexOffset: 10
        },
        showArea: false
      }
    }
  };

  // 清除现有绘制控件
  if (drawControl) {
    mapInstance.removeControl(drawControl);
    mapInstance.off('draw:created');
    mapInstance.off('draw:edited');
    drawControl = null;
    polygonDrawHandler = null;
  }

  try {
    if (typeof L.Control.Draw !== 'function') {
      throw new Error('Leaflet.Draw插件未正确加载');
    }

    drawControl = new (L.Control.Draw as any)(drawOptions);
    mapInstance.addControl(drawControl);

    let handlers: DrawHandlerCollection | null = null;

    // 兼容不同版本的Leaflet.Draw
    if (drawControl.handlers) {
      handlers = drawControl.handlers as DrawHandlerCollection;
    } else if (drawControl._drawHandlers) {
      handlers = drawControl._drawHandlers as DrawHandlerCollection;
    } else if (drawControl._toolbar && drawControl._toolbar._modes) {
      handlers = drawControl._toolbar._modes as DrawHandlerCollection;
    } else {
      polygonDrawHandler = new (L.Draw.Polygon as any)(mapInstance, drawOptions.draw.polygon);
    }

    if (handlers) {
      if ('polygon' in handlers) {
        polygonDrawHandler = handlers.polygon;
      } else if ('Polygon' in handlers) {
        polygonDrawHandler = handlers.Polygon;
      }
    }

    // 初始化绘制状态
    if (polygonDrawHandler && typeof polygonDrawHandler.enable === 'function') {
      polygonDrawHandler.disable();
      setMessage('绘制功能初始化完成');
    } else {
      setMessage('正在使用兼容模式初始化绘制功能', 3000);
      polygonDrawHandler = {
        _isDrawing: false,
        enable: function () {
          this._isDrawing = true;
        },
        disable: function () {
          this._isDrawing = false;
        },
        finishDrawing: function () {
          this._isDrawing = false;
        }
      } as L.DrawHandler;
    }
  } catch (error) {
    setMessage(`绘制控件初始化失败: ${(error as Error).message}`, 5000);
    console.error('绘制控件初始化错误:', error);
  }

  // 绘制完成事件处理
  mapInstance.off('draw:created').on('draw:created', (e: any) => {
    const {layerType, layer} = e;
    if (layerType !== 'polygon' || !polygonLayer || !selectedConfigId.value) {
      if (layer && polygonLayer && polygonLayer.hasLayer(layer)) {
        polygonLayer.removeLayer(layer);
      }
      setMessage('请先选择配置组或绘制多边形', 3000);
      return;
    }

    // 处理多边形创建
    const latLngs = layer.getLatLngs() as L.LatLng[][];
    const coordinates = latLngs.map(ring => ring.map(p => [p.lat, p.lng]));
    const points: MapPolygonPoint[] = [];
    latLngs.forEach((ring, ringIndex) => {
      ring.forEach((p, pointIndex) => {
        points.push({
          ringIndex,
          lng: p.lng,
          lat: p.lat,
          pointIndex
        });
      });
    });

    // 提取外环顶点用于面积计算（简单多边形取第一个环）
    const outerRingPoints = latLngs[0].map(p => [p.lng, p.lat] as [number, number]);
    // 计算面积
    const area = calculatePolygonArea(outerRingPoints);

    const newPolygon: MapPolygon = {
      configId: selectedConfigId.value,
      name: `多边形${polygons.value.length + 1}`,
      strokeColor: '#4ecdc4',
      strokeWeight: 2,
      fillColor: '#4ecdc4',
      fillOpacity: 0.3,
      roomLevel: 13,
      sortOrder: polygons.value.length,
      points,
      coordinates,
      area,
      pointCount: points.length
    };

    polygons.value.push(newPolygon);

    // 设置多边形样式
    layer.setStyle({
      color: newPolygon.strokeColor,
      weight: newPolygon.strokeWeight,
      fillColor: newPolygon.fillColor,
      fillOpacity: newPolygon.fillOpacity,
      zIndexOffset: newPolygon.roomLevel
    });

    // 添加面积弹窗
    layer.bindPopup(`<b>${newPolygon.name}</b><br>面积: ${formatArea(area)} ${getAreaUnitLabel()}`);

    if (!polygonLayer.hasLayer(layer)) {
      polygonLayer.addLayer(layer);
    }

    addPolygonClickEvent(layer, newPolygon);

    // 自动调整地图视野以包含新绘制的多边形，增加最大缩放限制
    if (mapInstance) {
      const bounds = layer.getBounds();
      mapInstance.fitBounds(bounds, {
        padding: [50, 50],
        maxZoom: 15
      });
    }

    // 强制退出绘制模式
    setTimeout(() => {
      forceExitDrawMode();
    }, 100);

    setMessage(`已绘制${points.length}个顶点的多边形，面积: ${formatArea(area)} ${getAreaUnitLabel()}`);
  });

  // 编辑完成事件处理
  mapInstance.off('draw:edited').on('draw:edited', (e: any) => {
    if (!polygonLayer) return;

    e.layers.eachLayer((layer: L.Polygon) => {
      const latLngs = layer.getLatLngs() as L.LatLng[][];
      const coordinates = latLngs.map(ring => ring.map(p => [p.lat, p.lng]));
      const points: MapPolygonPoint[] = [];
      latLngs.forEach((ring, ringIndex) => {
        ring.forEach((p, pointIndex) => {
          points.push({ringIndex, lng: p.lng, lat: p.lat, pointIndex});
        });
      });

      // 计算编辑后的面积
      const outerRingPoints = latLngs[0].map(p => [p.lng, p.lat] as [number, number]);
      const area = calculatePolygonArea(outerRingPoints);

      const index = polygons.value.findIndex(p =>
        JSON.stringify(p.coordinates) === JSON.stringify(coordinates)
      );
      if (index !== -1) {
        polygons.value[index].coordinates = coordinates;
        polygons.value[index].points = points;
        polygons.value[index].area = area;
        polygons.value[index].pointCount = points.length;

        // 更新弹窗信息
        layer.bindPopup(`<b>${polygons.value[index].name}</b><br>面积: ${formatArea(area)} ${getAreaUnitLabel()}`);

        setMessage(`多边形已更新，面积: ${formatArea(area)} ${getAreaUnitLabel()}`);
      }
    });
  });
};

// 处理地图点击事件 - 新增方法
const handleMapClick = (e: L.LeafletMouseEvent) => {
  // 如果不在拾取坐标状态，不处理
  if (!pickingCoordinate.value) return;

  const {lng, lat} = e.latlng;

  // 根据当前拾取类型更新对应的值
  if (pickingCoordinate.value === 'lng') {
    judgeReq.value.lng = parseFloat(lng.toFixed(6));
  } else if (pickingCoordinate.value === 'lat') {
    judgeReq.value.lat = parseFloat(lat.toFixed(6));
  }

  // 更新或创建临时标记
  updateTempMarker(lng, lat);

  // 自动退出拾取状态
  setTimeout(() => {
    pickingCoordinate.value = '';
  }, 500);
};

// 更新临时标记 - 新增方法
const updateTempMarker = (lng: number, lat: number) => {
  if (!mapInstance) return;

  // 移除旧的临时标记 - 明确类型转换
  if (tempMarker.value) {
    mapInstance.removeLayer(tempMarker.value as unknown as L.Layer);
  }

  // 创建新的临时标记
  tempMarker.value = L.marker([lat, lng], {
    icon: L.divIcon({
      className: 'temp-marker',
      html: '<div class="marker-pulse"></div>',
      iconSize: [20, 20],
      iconAnchor: [10, 10]
    })
  }).addTo(mapInstance);

  // 绑定弹窗显示坐标信息
  tempMarker.value.bindPopup(`
    <b>选中点</b><br>
    经度: ${lng.toFixed(6)}<br>
    纬度: ${lat.toFixed(6)}
  `).openPopup();
};

// 开始拾取坐标 - 新增方法
const startPickCoordinate = (type: 'lng' | 'lat') => {
  if (!mapInstance) {
    setMessage('地图未初始化', 3000);
    return;
  }

  // 如果已经在拾取状态，切换或取消
  if (pickingCoordinate.value === type) {
    pickingCoordinate.value = '';
    return;
  }

  // 设置拾取状态
  pickingCoordinate.value = type;

  // 更改鼠标样式提示用户
  const mapContainer = mapInstance.getContainer();
  mapContainer.style.cursor = 'crosshair';

  // 显示提示信息
  setMessage(`请在地图上点击拾取${type === 'lng' ? '经度' : '纬度'}`, 3000);
};

// 获取当前位置并填充 - 新增方法
// const pickCurrentLocation = () => {
//   if (!navigator.geolocation) {
//     setMessage('浏览器不支持地理位置获取', 3000);
//     return;
//   }
//
//   setMessage('正在获取当前位置...', 0);
//
//   navigator.geolocation.getCurrentPosition(
//     (position) => {
//       const { longitude, latitude } = position.coords;
//
//       // 填充坐标
//       judgeReq.value.lng = parseFloat(longitude.toFixed(6));
//       judgeReq.value.lat = parseFloat(latitude.toFixed(6));
//
//       // 在地图上标记
//       updateTempMarker(longitude, latitude);
//
//       // 移动地图到当前位置
//       if (mapInstance) {
//         mapInstance.setView([latitude, longitude], 15);
//       }
//
//       setMessage('已获取当前位置', 3000);
//     },
//     (error) => {
//       console.error('获取位置失败:', error);
//       switch (error.code) {
//         case 1:
//           setMessage('请允许位置权限以获取当前位置', 3000);
//           break;
//         case 2:
//           setMessage('无法获取位置信息，请稍后重试', 3000);
//           break;
//         case 3:
//           setMessage('获取位置超时', 3000);
//           break;
//         default:
//           setMessage('获取位置失败', 3000);
//       }
//     },
//     {
//       enableHighAccuracy: true,
//       timeout: 10000,
//       maximumAge: 0
//     }
//   );
// };

// 获取面积单位标签
const getAreaUnitLabel = (): string => {
  switch (areaUnit.value) {
    case 'sqkm':
      return '平方公里';
    case 'sqmi':
      return '平方英里';
    default:
      return '平方米';
  }
};

// 强制退出绘制模式
const forceExitDrawMode = () => {
  if (!mapInstance) return;

  // 强制设置状态为非绘制中
  isDrawing.value = false;

  // 禁用绘制处理器
  if (polygonDrawHandler) {
    if (polygonDrawHandler._isDrawing) {
      polygonDrawHandler._isDrawing = false;
    }
    if (typeof polygonDrawHandler.disable === 'function') {
      polygonDrawHandler.disable();
    }
  }

  // 禁用绘制控件
  if (drawControl) {
    if (typeof drawControl.disableDraw === 'function') {
      drawControl.disableDraw('polygon');
    }
    if (drawControl._editHandler) {
      drawControl._editHandler.enable();
    }
  }

  // 恢复鼠标样式
  const mapContainer = mapInstance.getContainer();
  mapContainer?.setAttribute('style', 'cursor: default');

  setMessage('已完成绘制，可编辑或保存多边形');
};

// 根据证件号码搜索人员
const personData = ref<UserApi.Person | null>(null);
const searchPerson = async () => {
  // 重置之前的错误信息
  searchError.value = '';

  // 验证输入
  const idNumber = judgeReq.value.idcard.trim();
  if (!idNumber) {
    searchError.value = '请输入证件号';
    return;
  }

  try {
    loading.value = true;
    // 调用API查询人员

    const result = await UserApi.getPersonByIdCard(idNumber);

    if (result) {
      personData.value = result;
      judgeReq.value.personId = result.id;
      // 可以在这里添加成功提示
      setMessage('人员查询成功', 2000);
    } else {
      // 未找到人员
      personData.value = null;
      judgeReq.value.personId = null;
      searchError.value = '未找到匹配的人员信息';
    }
  } catch (error) {
    // 处理错误
    personData.value = null;
    judgeReq.value.personId = null;

    console.error('人员查询失败:', error);
    if (error instanceof Error) {
      searchError.value = `查询失败: ${error.message}`;
    } else {
      searchError.value = '查询失败，请稍后重试';
    }
  } finally {
    loading.value = false;
  }
};

// 多边形点击事件
const addPolygonClickEvent = (layer: L.Polygon, polygon: MapPolygon) => {
  layer.off('click').on('click', () => {
    selectedPolygon.value = {...polygon};
  });
};

// 切换绘制模式
const toggleDrawMode = () => {
  if (!polygonDrawHandler) {
    setMessage('绘制功能未就绪，正在重试初始化...', 3000);
    initDrawControl();

    setTimeout(() => {
      if (polygonDrawHandler) {
        toggleDrawMode();
      } else {
        setMessage('绘制功能初始化失败，请检查Leaflet.Draw版本', 5000);
      }
    }, 1000);
    return;
  }

  // 如果当前正在绘制，强制结束
  if (isDrawing.value && polygonDrawHandler._isDrawing) {
    forceExitDrawMode();
    return;
  }

  isDrawing.value = !isDrawing.value;
  const mapContainer = mapInstance?.getContainer();

  if (isDrawing.value) {
    if (!selectedConfigId.value) {
      setMessage('请先选择配置组', 3000);
      isDrawing.value = false;
      return;
    }

    if (typeof polygonDrawHandler.enable === 'function') {
      polygonDrawHandler.enable();
    } else if (drawControl && typeof drawControl.enableDraw === 'function') {
      drawControl.enableDraw('polygon');
    }

    if (drawControl && drawControl._editHandler) {
      drawControl._editHandler.disable();
    }

    mapContainer?.setAttribute('style', 'cursor: crosshair');
    setMessage('点击添加顶点，双击结束绘制');
  } else {
    forceExitDrawMode();
  }
};

// 保存所有多边形
const saveAllPolygons = async () => {
  // 保存前强制退出绘制模式
  if (isDrawing.value) {
    forceExitDrawMode();
    await new Promise(resolve => setTimeout(resolve, 300));
  }

  if (polygons.value.length === 0) {
    setMessage('没有可保存的多边形', 3000);
    return;
  }
  if (!selectedConfigId.value) {
    setMessage('请先选择配置组', 3000);
    return;
  }

  try {
    const validPolygons = polygons.value.filter(poly =>
      poly.points && poly.points.length > 0 && poly.configId
    );

    if (validPolygons.length === 0) {
      setMessage('没有有效的多边形数据可保存', 3000);
      return;
    }

    for (const poly of validPolygons) {
      const reqData = {
        id: poly.id,
        configId: poly.configId,
        name: poly.name,
        strokeColor: poly.strokeColor,
        strokeWeight: poly.strokeWeight,
        fillColor: poly.fillColor,
        fillOpacity: poly.fillOpacity,
        roomLevel: 13,
        sortOrder: poly.sortOrder,
        points: poly.points,
        area: poly.area  // 保存面积信息
      };
      console.log("reqData==>", reqData)
      if (poly.id) {
        await MapPolygonApi.updateMapPolygon(reqData);
      } else {
        const res = await MapPolygonApi.createMapPolygon(reqData);
        if (res?.id) {
          poly.id = res.id;
        }
      }
    }

    setMessage(`已成功保存${validPolygons.length}个多边形`, 3000);
    loadPolygonsByConfigId(selectedConfigId.value);
  } catch (error) {
    setMessage('保存多边形失败', 3000);
    console.error(error);
  }
};

// 计算所有多边形的边界范围
const calculatePolygonsBounds = (polygons: MapPolygon[]): L.LatLngBounds | null => {
  if (!polygons || polygons.length === 0) return null;

  // 创建一个空的边界对象
  let bounds = L.latLngBounds([]);

  polygons.forEach(poly => {
    const points = poly.points || [];
    points.forEach(point => {
      // 将每个点添加到边界范围
      bounds.extend([point.lat, point.lng]);
    });
  });

  // 如果边界有效则返回，否则返回null
  return bounds.isValid() ? bounds : null;
};

// 重新加载多边形
const loadAllPolygons = async () => {
  if (!selectedConfigId.value) {
    setMessage('请先选择配置组', 3000);
    return;
  }
  await loadPolygonsByConfigId(selectedConfigId.value);
};

// 清空所有多边形
const clearAllPolygons = () => {
  if (polygons.value.length === 0) {
    setMessage('没有可清空的多边形', 3000);
    return;
  }

  if (confirm('确定要清空所有多边形吗？未保存的更改将会丢失。')) {
    polygons.value = [];
    polygonLayer?.clearLayers();
    selectedPolygon.value = null;
    setMessage('已清空所有多边形', 3000);
  }
};

// 更新多边形属性 - 完整修复版
const updatePolygon = () => {
  // 1. 基础检查
  if (!selectedPolygon.value) {
    setMessage('未选中任何多边形', 3000);
    return;
  }

  // 2. 检查加载状态，避免重复操作
  if (state.isLoadingPolygons) {
    setMessage('操作正在处理中，请稍候...', 3000);
    return;
  }

  // 3. 关键检查：polygons数组是否为空
  if (polygons.value.length === 0) {
    setMessage('多边形数据为空，尝试重新加载...', 3000);
    console.warn('polygons数组为空，尝试重新加载数据', {
      selectedPolygonId: selectedPolygon.value.id,
      selectedPolygonName: selectedPolygon.value.name,
      configId: selectedConfigId.value,
      timestamp: new Date().toISOString()
    });

    // 自动重新加载数据
    if (selectedConfigId.value) {
      // 设置加载状态
      state.isLoadingPolygons = true;

      loadPolygonsByConfigId(selectedConfigId.value)
        .then(() => {
          state.isLoadingPolygons = false;
          // 重新加载后再次尝试更新
          setTimeout(() => {
            if (polygons.value.length > 0) {
              console.log('重新加载成功，尝试再次更新多边形', {
                polygonCount: polygons.value.length,
                firstPolygonId: polygons.value[0]?.id
              });
              updatePolygon(); // 递归调用一次
            } else {
              setMessage('重新加载多边形数据失败，未获取到任何数据', 3000);
              console.error('重新加载后polygons仍为空', {
                configId: selectedConfigId.value
              });
            }
          }, 500);
        })
        .catch((error) => {
          state.isLoadingPolygons = false;
          setMessage('重新加载多边形数据时发生错误', 3000);
          console.error('重新加载多边形失败', error);
        });
    } else {
      setMessage('缺少配置ID，无法重新加载多边形数据', 3000);
      console.error('selectedConfigId为空，无法加载数据');
    }
    return;
  }

  console.log('尝试更新多边形:', {
    id: selectedPolygon.value.id,
    name: selectedPolygon.value.name,
    pointCount: selectedPolygon.value.pointCount,
    polygonsCount: polygons.value.length
  });

  // 4. 多级查找机制
  let index = polygons.value.findIndex(p =>
    p.id && selectedPolygon.value!.id && p.id === selectedPolygon.value!.id
  );

  if (index === -1 && selectedPolygon.value.name) {
    console.log(`通过id未找到，尝试通过名称 "${selectedPolygon.value.name}" 和顶点数量 ${selectedPolygon.value.pointCount} 查找`);
    index = polygons.value.findIndex(p =>
      p.name === selectedPolygon.value!.name &&
      p.pointCount === selectedPolygon.value!.pointCount
    );
  }

  if (index === -1) {
    console.log('通过名称和顶点数量未找到，尝试通过坐标查找');
    try {
      if (!selectedPolygon.value) {
        console.error('selectedPolygon为null，无法进行坐标比较');
        return;
      }

      const selectedPoints = selectedPolygon.value.points.slice(0, 3);
      index = polygons.value.findIndex(poly => {
        if (poly.points.length !== selectedPolygon.value!.points.length) return false;

        const polyPoints = poly.points.slice(0, 3);
        return selectedPoints.every((sp, i) => {
          const pp = polyPoints[i];
          if (!pp) return false;
          const lngDiff = Math.abs(sp.lng - pp.lng);
          const latDiff = Math.abs(sp.lat - pp.lat);
          return lngDiff < 0.00001 && latDiff < 0.00001;
        });
      });
    } catch (err) {
      console.error('坐标比较出错:', err);
    }
  }

  // 5. 最终检查与处理
  if (index === -1) {
    setMessage('未找到对应的多边形', 5000);
    console.error('未找到要更新的多边形，详细信息:', {
      selectedPolygon: {
        id: selectedPolygon.value.id,
        name: selectedPolygon.value.name,
        pointCount: selectedPolygon.value.pointCount
      },
      existingPolygons: polygons.value.map(p => ({
        id: p.id,
        name: p.name,
        pointCount: p.pointCount
      })),
      configId: selectedConfigId.value
    });

    // 提供手动重新加载选项
    if (confirm('未找到多边形数据，是否尝试重新加载？')) {
      if (selectedConfigId.value) {
        loadPolygonsByConfigId(selectedConfigId.value);
      }
    }
    return;
  }

  // 6. 执行更新逻辑
  try {
    const originalPoly = polygons.value[index];
    const pointsChanged = JSON.stringify(originalPoly.points) !== JSON.stringify(selectedPolygon.value.points);

    if (pointsChanged) {
      const outerRingPoints = selectedPolygon.value.points
        .filter(p => p.ringIndex === 0)
        .sort((a, b) => a.pointIndex - b.pointIndex)
        .map(p => [p.lng, p.lat] as [number, number]);

      selectedPolygon.value.area = calculatePolygonArea(outerRingPoints);
      selectedPolygon.value.pointCount = selectedPolygon.value.points.length;
    }

    // 使用splice确保响应式更新
    polygons.value.splice(index, 1, {...selectedPolygon.value});

    // 重新渲染多边形
    if (polygonLayer) {
      polygonLayer.clearLayers();
      polygons.value.forEach(poly => {
        const ringMap: Record<number, L.LatLng[]> = {};
        poly.points.forEach((p) => {
          const ringIndex = p.ringIndex || 0;
          if (!ringMap[ringIndex]) {
            ringMap[ringIndex] = [];
          }
          ringMap[ringIndex].push(L.latLng(p.lat, p.lng));
        });

        const latLngs = Object.keys(ringMap)
          .sort((a, b) => Number(a) - Number(b))
          .map(key => ringMap[Number(key)]);

        const layer = L.polygon(latLngs, {
          color: poly.strokeColor,
          weight: poly.strokeWeight,
          fillColor: poly.fillColor,
          fillOpacity: poly.fillOpacity,
          zIndexOffset: poly.roomLevel
        }).addTo(polygonLayer!);

        layer.bindPopup(`<b>${poly.name}</b><br>面积: ${formatArea(poly.area || 0)} ${getAreaUnitLabel()}`);
        addPolygonClickEvent(layer, poly);
      });
    }

    // 调整视野
    if (mapInstance && polygons.value.length > 0) {
      const bounds = calculatePolygonsBounds(polygons.value);
      if (bounds) {
        mapInstance.fitBounds(bounds, {
          padding: [50, 50],
          maxZoom: 15
        });
      }
    }

    setMessage(`多边形已更新${pointsChanged ? '，面积: ' + formatArea(selectedPolygon.value.area || 0) + ' ' + getAreaUnitLabel() : ''}`);
    selectedPolygon.value = null;
  } catch (error) {
    setMessage('更新多边形失败', 3000);
    console.error('更新多边形时出错:', error);
  }
};

// 加载多边形数据 - 完整修复版
const loadPolygonsByConfigId = async (configId: string) => {
  // 验证参数
  if (!configId) {
    console.error('loadPolygonsByConfigId: 配置ID为空');
    return Promise.reject(new Error('配置ID不能为空'));
  }

  // 避免重复加载
  if (state.isLoadingPolygons) {
    console.log('已有加载请求正在进行中，等待完成');
    return new Promise(resolve => {
      const checkLoading = setInterval(() => {
        if (!state.isLoadingPolygons) {
          clearInterval(checkLoading);
          resolve(undefined);
        }
      }, 100);
    });
  }

  // 设置加载状态
  state.isLoadingPolygons = true;
  try {
    setMessage('正在加载多边形数据...');
    console.log('开始加载多边形数据', {
      configId,
      timestamp: new Date().toISOString()
    });

    // 调用API加载数据
    const res = await MapPolygonApi.getPolygonsByConfigId(configId);

    // 记录响应信息
    console.log('多边形数据加载响应', {
      configId,
      hasResponse: !!res,
      responseLength: res?.length || 0,
      timestamp: new Date().toISOString()
    });

    if (res) {
      const polygonList = res;
      polygons.value = []; // 清空现有数据
      polygonLayer?.clearLayers();

      // 处理空数据情况
      if (polygonList.length === 0) {
        setMessage('当前配置下没有多边形数据', 3000);
        console.log('当前配置下无多边形数据', {configId});
        return;
      }

      // 处理并添加多边形
      polygonList.forEach((poly: MapPolygon) => {
        const points = poly.points || [];

        const ringMap: Record<number, L.LatLng[]> = {};
        points.forEach((p) => {
          const ringIndex = p.ringIndex || 0;
          if (!ringMap[ringIndex]) {
            ringMap[ringIndex] = [];
          }
          ringMap[ringIndex].push(L.latLng(p.lat, p.lng));
        });

        const latLngs = Object.keys(ringMap)
          .sort((a, b) => Number(a) - Number(b))
          .map(key => ringMap[Number(key)]);

        const layer = L.polygon(latLngs, {
          color: poly.strokeColor,
          weight: poly.strokeWeight,
          fillColor: poly.fillColor,
          fillOpacity: poly.fillOpacity,
          zIndexOffset: poly.roomLevel || 0
        }).addTo(polygonLayer!);

        // 计算面积（如果不存在）
        if (poly.area === undefined || poly.area === null) {
          const outerRingPoints = latLngs[0].map(p => [p.lng, p.lat] as [number, number]);
          poly.area = calculatePolygonArea(outerRingPoints);
        }

        // 设置弹窗和点击事件
        layer.bindPopup(`<b>${poly.name}</b><br>面积: ${formatArea(poly.area || 0)} ${getAreaUnitLabel()}`);
        addPolygonClickEvent(layer, poly);

        // 设置顶点数量
        poly.pointCount = points.length;

        // 添加到数组（确保响应式）
        polygons.value.push(poly);
      });

      // 调整地图视野
      if (mapInstance && polygonList.length > 0) {
        const bounds = calculatePolygonsBounds(polygonList);
        if (bounds) {
          mapInstance.fitBounds(bounds, {
            padding: [50, 50],
            maxZoom: 15
          });
        }
      }

      setMessage(`已加载${polygonList.length}个多边形`);
      console.log('多边形数据加载完成', {
        configId,
        count: polygonList.length,
        polygonIds: polygonList.map(p => p.id)
      });
    } else {
      console.warn('加载多边形数据返回空响应', {configId});
      setMessage('未获取到多边形数据', 3000);
    }

    return Promise.resolve();
  } catch (error) {
    setMessage('加载多边形失败', 3000);
    console.error('加载多边形错误:', {
      configId,
      error: error instanceof Error ? error.message : String(error),
      stack: error instanceof Error ? error.stack : undefined
    });
    return Promise.reject(error);
  } finally {
    // 确保无论成功失败都清除加载状态
    state.isLoadingPolygons = false;
  }
};

// 删除选中的多边形
const deleteSelectedPolygon = async () => {
  if (!selectedPolygon.value) return;

  if (confirm(`确定要删除多边形"${selectedPolygon.value.name}"吗？`)) {
    try {
      if (selectedPolygon.value.id) {
        await MapPolygonApi.deleteMapPolygon(selectedPolygon.value.id);
      }

      const index = polygons.value.findIndex(p => p.id === selectedPolygon.value!.id);
      if (index !== -1) {
        polygons.value.splice(index, 1);
      }

      polygonLayer?.clearLayers();
      polygons.value.forEach(poly => {
        const ringMap: Record<number, L.LatLng[]> = {};
        poly.points.forEach((p) => {
          const ringIndex = p.ringIndex || 0;
          if (!ringMap[ringIndex]) {
            ringMap[ringIndex] = [];
          }
          ringMap[ringIndex].push(L.latLng(p.lat, p.lng));
        });

        const latLngs = Object.keys(ringMap)
          .sort((a, b) => Number(a) - Number(b))
          .map(key => ringMap[Number(key)]);

        const layer = L.polygon(latLngs, {
          color: poly.strokeColor,
          weight: poly.strokeWeight,
          fillColor: poly.fillColor,
          fillOpacity: poly.fillOpacity,
          zIndexOffset: poly.roomLevel
        }).addTo(polygonLayer!);

        layer.bindPopup(`<b>${poly.name}</b><br>面积: ${formatArea(poly.area || 0)} ${getAreaUnitLabel()}`);

        addPolygonClickEvent(layer, poly);
      });

      // 删除后调整视野以包含剩余多边形，增加最大缩放限制
      if (mapInstance && polygons.value.length > 0) {
        const bounds = calculatePolygonsBounds(polygons.value);
        if (bounds) {
          mapInstance.fitBounds(bounds, {
            padding: [50, 50],
            maxZoom: 15
          });
        }
      }

      selectedPolygon.value = null;
      setMessage('多边形已删除', 3000);
    } catch (error) {
      setMessage('删除多边形失败', 3000);
      console.error(error);
    }
  }
};

// 取消选中多边形
const deselectPolygon = () => {
  selectedPolygon.value = null;
};

// 获取配置列表
const getConfigPage = async () => {
  try {
    const params = {
      pageNo: pageParam.value.pageNo,
      pageSize: pageParam.value.pageSize,
      keyword: searchKeyword.value,
      idNumber: searchIdNumber.value,
      fenceType: searchFenceType.value,
      fenceStatus: searchFenceStatus.value,
      warnType: 1
    };

    const res = await MapConfigApi.getMapConfigPage(params);
    if (res) {
      configPage.value.list = res.list || [];
      configPage.value.total = res.total || 0;
    }
  } catch (error) {
    setMessage('获取配置列表失败', 3000);
    console.error(error);
  }
};

// 搜索配置
const handleSearch = () => {
  pageParam.value.pageNo = 1;
  getConfigPage();
};

// 清空搜索条件
const clearSearch = () => {
  // 重置所有搜索绑定的变量
  searchKeyword.value = '';
  searchIdNumber.value = '';
  searchFenceType.value = undefined;
  searchFenceStatus.value = undefined;
  // 可选：清空后自动执行一次搜索，显示所有数据
  handleSearch();
};

// 点击配置行
// const handleConfigClick = (row: MapConfig) => {
//   handleViewMap(row);
// };

// 查看地图
const handleViewMap = (row: MapConfig) => {
  selectedConfigId.value = row.id;
  currentConfigId.value = row.id;
  currentConfig.value = row;
  judgeReq.value.configId = row.id;
  showMapDialog.value = true;
  setTimeout(() => {
    // 先初始化地图，使用配置的中心点和缩放级别
    initMap(row.centerLng, row.centerLat, row.zoomLevel);
    // 加载多边形后会自动调整视野
    loadPolygonsByConfigId(row.id);
  }, 100);
};

// 表格行样式
const rowClassNameHandler = ({row}: { row: MapConfig }) => {
  return row.id === selectedConfigId.value ? 'selected-config' : '';
};

// 打开新增配置弹窗
const openCreateConfigDialog = () => {
  isEditConfig.value = false;
  const now = new Date();
  const defaultEndTime = new Date(now);
  configForm.value = {
    id: '',
    name: '',
    description: '',
    provinceCode: '330000',
    cityCode: '330100',
    districtCode: '',
    centerLng: 120.1551,
    centerLat: 30.2741,
    zoomLevel: 13,
    isDefault: 0,
    startTime: now.toISOString().slice(0, 19).replace('T', ' '),
    endTime: defaultEndTime.toISOString().slice(0, 19).replace('T', ' '),
    warnType: 1,
    fenceType: 1
  };
  showConfigDialog.value = true;
};

// 编辑配置
const handleEditConfig = (row: MapConfig) => {
  isEditConfig.value = true;
  configForm.value = {
    ...row,
    warnType: 3,
    startTime: row.startTime ? new Date(row.startTime).toISOString().slice(0, 19).replace('T', ' ') : '',
    endTime: row.endTime ? new Date(row.endTime).toISOString().slice(0, 19).replace('T', ' ') : ''
  };
  showConfigDialog.value = true;
};

// 删除配置
const handleDeleteConfig = async (id: string) => {
  if (confirm('确定要删除该配置吗？关联的多边形也会被删除。')) {
    try {
      await MapConfigApi.deleteMapConfig(id);
      setMessage('配置已删除', 3000);
      getConfigPage();
      if (id === selectedConfigId.value) {
        selectedConfigId.value = '';
        currentConfigId.value = '';
        currentConfig.value = null;
        polygons.value = [];
        if (polygonLayer) {
          polygonLayer.clearLayers();
        }
      }
    } catch (error) {
      setMessage('删除配置失败', 3000);
      console.error(error);
    }
  }
};

// 提交配置表单
const submitConfigForm = async () => {

  if (!configForm.value.name) {
    setMessage('请填写必填字段', 3000);
    return;
  }
  try {
    configForm.value.warnType = 1;
    if (isEditConfig.value) {
      await MapConfigApi.updateMapConfig(configForm.value);
      setMessage('配置已更新', 3000);
    } else {
      await MapConfigApi.createMapConfig(configForm.value);
      setMessage('配置已创建', 3000);
    }

    showConfigDialog.value = false;
    await getConfigPage();
  } catch (error) {
    setMessage(isEditConfig.value ? '更新配置失败' : '创建配置失败', 3000);
    console.error(error);
  }
};

// 分页大小变更
const handlePageSizeChange = (size: number) => {
  pageParam.value.pageSize = size;
  pageParam.value.pageNo = 1;
  getConfigPage();
};

// 当前页变更
const handleCurrentChange = (page: number) => {
  pageParam.value.pageNo = page;
  getConfigPage();
};

// 判断点是否在多边形内
const judgePointInPolygon = async () => {
  if (!judgeReq.value.lng || !judgeReq.value.lat) {
    setMessage('请输入经纬度', 3000);
    return;
  }

  try {
    const res = await PointInPolygonApi.judge({
      configId: currentConfigId.value,
      lng: judgeReq.value.lng,
      lat: judgeReq.value.lat,
      personId: judgeReq.value.personId,
      idcard: judgeReq.value.idcard,
      address: judgeReq.value.address,
    });

    if (res) {
      judgeResult.value = res;

      if (mapInstance) {
        // 清除现有标记
        mapInstance.eachLayer(layer => {
          if ((layer as L.Marker).getLatLng) {
            mapInstance!.removeLayer(layer);
          }
        });

        // 添加新标记
        L.marker([judgeReq.value.lat, judgeReq.value.lng])
          .addTo(mapInstance)
          .bindPopup(`<b>判断点</b><br>Lng: ${judgeReq.value.lng}<br>Lat: ${judgeReq.value.lat}`)
          .openPopup();
      }
    }
  } catch (error) {
    setMessage('判断失败', 3000);
    console.error(error);
  }
};

// 生命周期 - 挂载时
onMounted(() => {
  getConfigPage();

  window.addEventListener('resize', () => {
    mapInstance?.invalidateSize();
  });
});

// 生命周期 - 卸载时
onUnmounted(() => {
  if (mapInstance) {
    mapInstance.remove();
    mapInstance = null;
  }
  window.removeEventListener('resize', () => {
    mapInstance?.invalidateSize();
  });
});

// 监听地图弹窗关闭
watch(showMapDialog, (newVal) => {
  if (!newVal && mapInstance) {
    mapInstance.remove();
    mapInstance = null;
    polygons.value = [];
    selectedPolygon.value = null;
    isDrawing.value = false;
    showPointJudge.value = false;
    judgeResult.value = null;
  }
});

// 监听面积单位变化，更新显示
watch(areaUnit, () => {
  if (selectedPolygon.value) {
    selectedPolygon.value = {...selectedPolygon.value};
  }

  // 更新所有多边形的弹窗显示
  if (polygonLayer) {
    polygonLayer.eachLayer((layer: L.Polygon) => {
      const latLngs = layer.getLatLngs() as L.LatLng[][];
      const coordinates = latLngs.map(ring => ring.map(p => [p.lat, p.lng]));

      const index = polygons.value.findIndex(p =>
        JSON.stringify(p.coordinates) === JSON.stringify(coordinates)
      );

      if (index !== -1) {
        const poly = polygons.value[index];
        layer.bindPopup(`<b>${poly.name}</b><br>面积: ${formatArea(poly.area || 0)} ${getAreaUnitLabel()}`);
      }
    });
  }
});

// 监听拾取状态变化 - 新增
watch(pickingCoordinate, (newVal, oldVal) => {
  if (!mapInstance) return;

  const mapContainer = mapInstance.getContainer();

  // 退出拾取状态时恢复鼠标样式
  if (!newVal && oldVal) {
    mapContainer.style.cursor = 'default';
  }
});

// 监听地图弹窗关闭 - 确保清理临时标记
watch(showMapDialog, (newVal) => {
  if (!newVal) {
    // 清理临时标记
    if (tempMarker.value && mapInstance) {
      mapInstance.removeLayer(tempMarker.value as unknown as L.Layer);
      tempMarker.value = null;
    }
    pickingCoordinate.value = '';
  }
});

</script>

<style scoped>
.config-page {
  padding: 20px;
  //max-width: 1400px;
  margin: 0 auto;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #e5e7eb;
}

.search-bar {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  max-width: 900px;
}

.search-bar .form-control {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.table-container {
  background-color: white;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.pagination-container {
  margin-top: 15px;
  text-align: right;
}

/* -------------- 可移动弹窗样式 -------------- */
/* 1. 弹窗标题栏鼠标样式（提示可拖拽） */
.draggable-dialog .el-dialog__header {
  cursor: move;
  user-select: none; /* 防止拖拽时选中标题文字 */
}

/* 2. 弹窗内容区鼠标样式（恢复默认，避免误触发拖拽） */
.draggable-dialog .el-dialog__body {
  cursor: default;
}

/* 3. 修复Element UI弹窗默认定位冲突 */
.draggable-dialog {
  position: fixed !important; /* 强制fixed定位，确保拖拽正常 */
  top: 50% !important; /* 初始位置居中（后续拖拽会覆盖） */
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important; /* 清除默认margin */
  transition: none !important; /* 禁用默认过渡动画，避免拖拽卡顿 */
}

/* -------------- 地图弹窗样式 -------------- */
.fixed-size-dialog {
  display: flex;
  flex-direction: column;
  max-height: 90vh !important;
  overflow: hidden;
}

.fixed-size-dialog .el-dialog__body {
  flex: 1;
  overflow: hidden;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.map-dialog-container {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  height: 100%;
}

.map {
  width: 100%;
  flex: 1;
  border-radius: 6px;
  min-height: 600px; /* 确保地图有最小高度 */
}

/* 地图控制按钮组 */
.map-controls {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 1000;
}

.control-btn {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
  background-color: white;
  color: #333;
}

.control-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.control-btn.active {
  background-color: #4ecdc4;
  color: white;
}

.save-btn {
  background-color: #42b983;
  color: white;
}

.clear-btn {
  background-color: #f44336;
  color: white;
}

.load-btn {
  background-color: #17a2b8;
  color: white;
}

.mr-1 {
  margin-right: 5px;
}

.polygon-info {
  position: absolute;
  bottom: 20px;
  left: 20px;
  background-color: white;
  padding: 15px;
  border-radius: 6px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  width: 300px;
  z-index: 1000;
  max-height: 70%;
  overflow-y: auto;
}

.form-group {
  margin-bottom: 12px;
}

.form-row {
  display: flex;
  gap: 10px;
}

.form-group.half {
  flex: 1;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
}

.required {
  color: #f44336;
}

.form-control {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-sizing: border-box;
}

/* 面积显示样式 */
.area-display {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.readonly-value {
  padding: 8px 12px;
  background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.area-unit-select {
  padding: 4px 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 12px;
}

.btn {
  padding: 8px 16px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  font-size: 14px;
  display: inline-flex;
  align-items: center;
}

.btn-primary {
  background-color: #42b983;
  color: white;
}

.btn-primary:hover {
  background-color: #359e75;
}

.btn-secondary {
  background-color: #e5e7eb;
  color: #374151;
}

.btn-secondary:hover {
  background-color: #d1d5db;
}

.btn-danger {
  background-color: #f44336;
  color: white;
}

.btn-danger:hover {
  background-color: #d32f2f;
}

.btn-info {
  background-color: #17a2b8;
  color: white;
  color: white;
}

.btn-info:hover {
  background-color: #117a8b;
}

.btn-sm {
  padding: 4px 8px;
  font-size: 12px;
  margin-right: 5px;
}

.polygon-info .btn {
  margin-right: 8px;
  margin-top: 10px;
}

/* 点-in-多边形判断面板样式 */
.point-judge {
  position: absolute;
  top: 10px;
  right: 70px;
  background-color: white;
  padding: 15px;
  border-radius: 6px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  width: 300px;
  z-index: 1000;
  max-height: 80vh;
  overflow-y: auto;
}

.judge-result {
  margin-top: 15px;
  padding-top: 10px;
  border-top: 1px dashed #eee;
}

.status-message {
  position: absolute;
  bottom: 20px;
  right: 20px;
  padding: 10px 15px;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  border-radius: 4px;
  z-index: 1000;
}

.selected-config {
  background-color: #e6f7ee;
}

.default-tag {
  display: inline-block;
  padding: 2px 8px;
  background-color: #42b983;
  color: white;
  border-radius: 12px;
  font-size: 12px;
}


/* 拾取按钮样式 */
.pick-btn {
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f0f0f0;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
}

.pick-btn:hover {
  background-color: #e0e0e0;
}

.pick-btn.active {
  background-color: #42b983;
  color: white;
  border-color: #42b983;
}

/* 拾取提示样式 */
.pick-notice {
  margin-top: 10px;
  padding: 5px 10px;
  background-color: #e6f7ee;
  color: #359e75;
  border-radius: 4px;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 5px;
}

/* 临时标记样式 */
.temp-marker {
  position: relative;
}

.marker-pulse {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: rgba(66, 185, 131, 0.7);
  border: 2px solid #42b983;
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0% {
    transform: scale(0.95);
    box-shadow: 0 0 0 0 rgba(66, 185, 131, 0.7);
  }

  70% {
    transform: scale(1);
    box-shadow: 0 0 0 10px rgba(66, 185, 131, 0);
  }

  100% {
    transform: scale(0.95);
    box-shadow: 0 0 0 0 rgba(66, 185, 131, 0);
  }
}

/* 点是否在多边形内-面板标题栏样式 */
.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

/* 关闭按钮样式 */
.close-btn {
  background: none;
  border: none;
  color: #666;
  cursor: pointer;
  font-size: 16px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.close-btn:hover {
  background-color: #f0f0f0;
  color: #f44336;
}

.custom-close-icon {
  position: relative;
}

.custom-close-icon::before,
.custom-close-icon::after {
  content: '';
  position: absolute;
  width: 2px;
  height: 16px;
  background-color: #666;
}

.custom-close-icon::before {
  transform: rotate(45deg);
}

.custom-close-icon::after {
  transform: rotate(-45deg);
}

.custom-close-icon:hover::before,
.custom-close-icon:hover::after {
  background-color: #f44336;
}
/* 点是否在多边形内-面板标题栏样式结束 */

/* 可选：调整按钮间距 */
.search-bar .btn {
  margin-left: 8px;
}

/* 可选：清空按钮悬停效果 */
.btn-outline-secondary:hover {
  background-color: #f5f5f5;
}
.btn-primary {
  background-color: #42b983;
  color: white;
}

.btn-warning {
  background-color: #f39c12; /* 橙色作为警告色主色调 */
  color: white; /* 白色文字确保可读性 */
}

/* 可选：添加悬停效果增强交互体验 */
.btn-warning:hover {
  background-color: #e67e22; /* 稍深的橙色作为悬停状态 */
}

:deep(.el-drawer__header) {
  margin-bottom: 0 !important;
}

</style>
